package com.sugree.twitter;

import java.util.Date;
import java.util.Vector;
import java.io.IOException;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.rms.RecordStoreException;

import com.substanceofcode.twitter.Settings;
import com.substanceofcode.twitter.TwitterApi;
import com.substanceofcode.twitter.model.Status;
import com.substanceofcode.utils.HttpUtil;
import com.substanceofcode.utils.StringUtil;
import com.substanceofcode.utils.Log;

import com.sugree.twitter.tasks.RequestTimelineTask;
import com.sugree.twitter.tasks.UpdateStatusTask;
import com.sugree.twitter.views.TimelineScreen;
import com.sugree.twitter.views.SetupScreen;
import com.sugree.twitter.views.StatusScreen;
import com.sugree.twitter.views.UpdateStatusScreen;
import com.sugree.twitter.views.InsertScreen;
import com.sugree.twitter.views.WaitScreen;
import com.sugree.twitter.views.AlertScreen;
import com.sugree.twitter.views.LogScreen;

public class TwitterController {
	public static final int SCREEN_CURRENT = 0;
	public static final int SCREEN_TIMELINE = 1;
	public static final int SCREEN_UPDATE = 2;

	private TwitterMIDlet midlet;
	private TwitterApi api;
	private Display display;
	private Settings settings;

	private TimelineScreen timeline;
	private UpdateStatusScreen update;
	private StatusScreen status;
	private InsertScreen insert;

	private int currentFeedType;

	public TwitterController(TwitterMIDlet midlet) {
		try {
			this.midlet = midlet;

			//HttpUtil.setUserAgent("jibjib/1.0.0 (j2me)" + " Profile/" + System.getProperty("microedition.profiles") + " Configuration/" + System.getProperty("microedition.configuration"));
			HttpUtil.setUserAgent("Profile/" + System.getProperty("microedition.profiles") + " Configuration/" + System.getProperty("microedition.configuration"));
			display = Display.getDisplay(midlet);
			api = new TwitterApi(TwitterMIDlet.NAME);
			settings = Settings.getInstance(midlet);
			api.setUsername(settings.getStringProperty(Settings.USERNAME, ""));
			api.setPassword(settings.getStringProperty(Settings.PASSWORD, ""));

			timeline = new TimelineScreen(this);
			update = new UpdateStatusScreen(this, "");
			insert = new InsertScreen(this);
			status = new StatusScreen(this);

			currentFeedType = -1;
		} catch (IOException e) {
			e.printStackTrace();
		} catch (RecordStoreException e) {
			e.printStackTrace();
		}
	}

	public Settings getSettings() {
		return settings;
	}

	public void exit() {
		try {
			midlet.destroyApp(true);
			midlet.notifyDestroyed();
		} catch (Exception e) {
			Log.error("Exit: "+e.toString());
		}
	}

	private Vector extractWords(Vector statuses) {
		Vector words = new Vector();

		for(int i=0; i<statuses.size(); i++) {
			Status status = (Status)statuses.elementAt(i);
			if (!words.contains("@"+status.getScreenName())) {
				words.addElement("@"+status.getScreenName());
			}
			String[] splited = StringUtil.split(status.getText(), " ");
			for(int j=0; j<splited.length; j++) {
				if (splited[j].length() > 1 &&
					(splited[j].charAt(0) == '@' || splited[j].charAt(0) == '#')) {
					if (!words.contains(splited[j])) {
						words.addElement(splited[j]);
					}
				}
			}
		}
		return words;
	}

	public void addTimeline(Vector statuses) {
		timeline.addTimeline(statuses);
		Vector words = extractWords(timeline.getTimeline());
		insert.setWords(words);
	}

	public String getLastStatus() {
		return timeline.getLastDate();
	}

	public void refresh() {
		display.setCurrent(display.getCurrent());
	}

	public void setCurrent(Displayable display) {
		this.display.setCurrent(display);
	}

	public void setCurrent(int id) {
		this.display.setCurrent(getScreen(id));
	}

	public void updateStatus(String text) {
		UpdateStatusTask task = new UpdateStatusTask(this, api, text);
		WaitScreen wait = new WaitScreen(this, task, SCREEN_UPDATE);
		wait.println("updating...");
		wait.start();
		display.setCurrent(wait);
	}

	public void fetchTimeline(int feedType) {
		if (feedType != currentFeedType) {
			timeline.clearTimeline();
		}
		currentFeedType = feedType;
		RequestTimelineTask task = new RequestTimelineTask(this, api, feedType);
		WaitScreen wait = new WaitScreen(this, task, SCREEN_TIMELINE);
		wait.println("fetching...");
		wait.start();
		display.setCurrent(wait);
	}

	public void showTimeline() {
		display.setCurrent(timeline);
	}

	public void showSetup() {
		SetupScreen setup = new SetupScreen(this, api);
		display.setCurrent(setup);
	}

	public void showLog() {
		LogScreen log = new LogScreen(this);
		display.setCurrent(log);
	}

	public void showStatus(Status status) {
		this.status.setStatus(status);
		display.setCurrent(this.status);
	}

	public void showUpdate() {
		showUpdate("");
	}

	public void showUpdate(String text) {
		update.setString(text);
		display.setCurrent(update);
	}

	public void showInsert() {
		display.setCurrent(insert);
	}

	public void insertUpdate(String text) {
		update.insert(text);
		display.setCurrent(update);
	}

	public void showAbout() {
		Alert about = new Alert("About", TwitterMIDlet.NAME+" "+TwitterMIDlet.VERSION+" developed by @sugree based on LoliTwitter by @pruet and Twim by @tlaukkanen.", null, AlertType.INFO);
		about.setTimeout(Alert.FOREVER);
		display.setCurrent(about);
	}

	public void showError(Exception e) {
		showError("Exception", e.getMessage(), AlertType.ERROR, SCREEN_CURRENT);
	}

	public void showError(Exception e, int nextDisplay) {
		showError("Exception", e.getMessage(), AlertType.ERROR, nextDisplay);
	}

	public void showError(String title, String text, AlertType type, int nextDisplay) {
		Displayable screen = getScreen(nextDisplay);
		Log.error(text);
		AlertScreen alert = new AlertScreen(this, title, text, screen);
		display.setCurrent(alert);
	}

	private Displayable getScreen(int id) {
		Displayable screen = display.getCurrent();
		switch (id) {
			case SCREEN_CURRENT:
				break;
			case SCREEN_TIMELINE:
				screen = timeline;
				break;
			case SCREEN_UPDATE:
				screen = update;
				break;
		}
		return screen;
	}
}
